/*----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the 
License at http://www.mozilla.org/MPL/
	
Software distributed under the License is distributed on 
an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, 
either express or implied. 
See the License for the specific language governing rights and 
limitations under the License.
	
The Original Code is Fever RS ( ActionScript 3 ) Framework code.
	
The Initial Developer of the Original Code is Romain Ecarnot.
Portions created by Initial Developer are Copyright (C) 2006
the Initial Developer. All Rights Reserved.
	
Contributor(s):
	
Unless required by applicable law or agreed to in writing, 
software distributed under the License is distributed on 
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
OF ANY KIND, either express or implied.
See the License for the specific language governing permissions 
and limitations under the License.
----------------------------------------------------------------------------*/

package fever.data.formatters 
{
	import fever.utils.StringUtil;		

	/**
	 * Formats a valid number adjusting the decimal rounding, precision and 
	 * the thousands separator character.
	 * 
	 * @author Romain Ecarnot
	 */
	public class NumberFormatter extends Formatter
	{
		//--------------------------------------------------------------------
		// Public properties
		//--------------------------------------------------------------------
		
		/**
		 * Decimal separator character to use when outputting formatted 
		 * decimal numbers.
		 * 
		 * @default '.'
		 */
		public var decimalSeparator : String;
		
		/**
		 * Number of decimal places to include in the output String.
		 * 
		 * @default -1
		 */
		public var precision : Number;
		
		/**
		 * Specifies how to round the number.
		 * 
		 * @default none
		 * @see fever.data.formatters.NumberBaseRoundType
		 */
		public var rounding : String;
		
		/**
		 * Character to use as the thousands separator in the 
		 * output String.
		 * 
		 * @default ' ' (white space).
		 */
		public var thousandsSeparator : String;
		
		/**
		 * If <code>true</code>, split the number into thousands increments 
		 * by using a separator character.
		 * 
		 * @default <code>true</code>
		 */
		public var useThousandsSeparator : Boolean;
		
		
		//--------------------------------------------------------------------
		// Public API
		//--------------------------------------------------------------------
		
		/**
		 * Constructs new <code>NumberFormatter</code> instance.
		 */
		public function NumberFormatter( )
		{
			super( getConstructorAccess() );
			
			decimalSeparator = '.';
			precision = -1;
			rounding = NumberBaseRoundType.NONE;
			thousandsSeparator = ' ';
			useThousandsSeparator = true;
		}		
		
		/**
		 * Formats and returns passed-in <code>value</code>.
		 * 
		 * @return Formatted String
		 */
		override public function format( value : * ) : String
		{
			if( isNaN(value) )
			{
				error = "Unable to format undefined or null Number";
				return "";
			}
			
			var integer : String = '';
			var decimal : String = '';
			var result : String = '';
			var tempDecimalSeparator : String = decimalSeparator;
			
			if( rounding != NumberBaseRoundType.NONE )
			{
				switch ( rounding )
				{
					case NumberBaseRoundType.DOWN : 
						value = Math.floor( value );
						break;
					case NumberBaseRoundType.UP :
						value = Math.ceil( value ); 
					case NumberBaseRoundType.NEAREST :
						value = Math.round( value );
						break;
					default : 
						error = "Invalid rounding type";
						return "";
				}
				integer = value.toString();
				tempDecimalSeparator = '';
				decimal = '';
			}
			else
			{
				var s : String = value.toString();
				if( s.indexOf( "." ) )
				{
					var part : Array = s.split( "." );
					integer = part[0];
					decimal = part[1];
					
					if( precision > 0 )
						decimal = decimal.substr(0, precision);	
				}
			}
			
			if( useThousandsSeparator )
			{
				var a : Array = new Array();
				var sp : Array = integer.split( "" );
				var i : int = sp.length;
				var j : int = -1;
				
				while( --i >= 0 )
				{
					if( ! ( ++j % 3) )
					{
						if( j != 0 ) a.push( thousandsSeparator );
						a.push( sp[i] );
					}	
					else a.push( sp[i] );		
				}
				
				a.reverse();
				integer = StringUtil.trim( a.join('') );
			}
			
			result = integer + tempDecimalSeparator + decimal;
			
			return result;
		}
	}
}
